﻿Imports System.IO
Imports SlimDX.Direct3D9

Public Class Bitmap

    Dim bitmaps As Array
    Dim pixelData() As Byte

    Public Count As Integer
    Dim MipCount As Integer
    Sub New(ByVal bitmTag As Magic.Core.Tag)
        If bitmTag Is Nothing Then Exit Sub
        MipCount = bitmTag(bitmTag.Xpe.IndexByName("mipmap count:levels"))

        bitmaps = bitmTag("bitmaps")
        Count = bitmaps.GetLength(0)
        pixelData = bitmTag("processed pixel data")
    End Sub
    Public Function Texture(Optional ByVal index As Integer = 0, Optional ByVal Lightmap As Boolean = False) As Texture
        Try
            Dim Size As Integer = 0
            Dim Offset As Integer = bitmaps.GetValue(index, 10)
            If Count > 1 Then
                If index = Count - 1 Then
                    Size = pixelData.Length - Offset
                Else
                    Size = bitmaps.GetValue(index + 1, 10) - Offset
                End If
            Else
                Size = pixelData.Length
            End If

            Dim DDS As New DDS_HEADER_STRUCTURE(bitmaps, index)
            Dim Raw(Size - 1) As Byte
            Array.Copy(pixelData, Offset, Raw, 0, Size)

            If Raw Is Nothing Then Return Nothing

            If Raw.Length = 0 Then Return Nothing

            Dim BitmapWidth As Integer = bitmaps.GetValue(index, 1)
            Dim BitmapHeight As Integer = bitmaps.GetValue(index, 2)
            Dim BitmapDepth As Integer = bitmaps.GetValue(index, 3)
            Dim bFormat As bitmFormat = bitmaps.GetValue(index, 5)

            Dim bFlags As bitmType = bitmaps.GetValue(index, 6)
            If (bFlags And &H8) > 0 Then
                Select Case bFormat
                    Case bitmFormat.BITM_FORMAT_DXT1
                        Raw = Raw
                    Case bitmFormat.BITM_FORMAT_DXT2AND3
                        Raw = Raw
                    Case bitmFormat.BITM_FORMAT_DXT4AND5
                        Raw = Raw
                    Case bitmFormat.BITM_FORMAT_A8
                        Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 8, SwizzleType.DeSwizzle)
                    Case bitmFormat.BITM_FORMAT_Y8
                        Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 8, SwizzleType.DeSwizzle)
                    Case bitmFormat.BITM_FORMAT_AY8
                        Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 8, SwizzleType.DeSwizzle)
                    Case bitmFormat.BITM_FORMAT_A8Y8
                        Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 16, SwizzleType.DeSwizzle)
                    Case bitmFormat.BITM_FORMAT_R5G6B5
                        Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 16, SwizzleType.DeSwizzle)
                    Case bitmFormat.BITM_FORMAT_A1R5G5B5
                        Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 16, SwizzleType.DeSwizzle)
                    Case bitmFormat.BITM_FORMAT_A4R4G4B4
                        Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 16, SwizzleType.DeSwizzle)
                    Case bitmFormat.BITM_FORMAT_X8R8G8B8
                        Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 32, SwizzleType.DeSwizzle)
                    Case bitmFormat.BITM_FORMAT_A8R8G8B8
                        Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 32, SwizzleType.DeSwizzle)
                    Case bitmFormat.BITM_FORMAT_P8
                        Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 8, SwizzleType.DeSwizzle)
                    Case bitmFormat.BITM_FORMAT_A8_LIGHTMAP
                        Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 8, SwizzleType.DeSwizzle)
                End Select
            End If
            If bFormat = bitmFormat.BITM_FORMAT_P8 Then
                bFormat = bitmFormat.BITM_FORMAT_A8R8G8B8
                Dim tBytes(Raw.Length * 4 - 1) As Byte
                For x As Integer = 0 To Raw.Length - 1

                    tBytes(x * 4) = Globals.NormalMaps(Raw(x) * 4)
                    tBytes(x * 4 + 1) = Globals.NormalMaps(Raw(x) * 4 + 1)
                    tBytes(x * 4 + 2) = Globals.NormalMaps(Raw(x) * 4 + 2)
                    tBytes(x * 4 + 3) = Globals.NormalMaps(Raw(x) * 4 + 3) 'Raw(x) 'IIf(Raw(x) = 0, 0, 255)
                Next
                Raw = tBytes
            End If

            Dim MS As New MemoryStream
            Dim BW As New BinaryWriter(MS)

            If bFormat = bitmFormat.BITM_FORMAT_A8 OrElse bFormat = bitmFormat.BITM_FORMAT_AY8 OrElse bFormat = bitmFormat.BITM_FORMAT_Y8 Then
                DDS.HeaderFlags = &H1007
                DDS.PixelFlags = 2
                DDS.RGBBitCount = 8
                DDS.RBitMask = 0
                DDS.GBitMask = 0
                DDS.BBitMask = 0
                DDS.RGBAlphaBitMask = &HFF
                DDS.Caps1 = &H1000
            End If
            If bFormat = bitmFormat.BITM_FORMAT_P8 Then
                DDS.MipMapCount = DDS.MipMapCount
            End If
            'DDS.MipMapCount = bitmaps.GetValue(index, 8)
            Dim firstMip As Integer = Magic.Core.Tag.CalculateBitmapSize(BitmapWidth, BitmapHeight, BitmapDepth, 0, bFormat, 0)

            DDS.writeStruct(BW)
            BW.Write(Raw) ', 0 , firstMip)
            BW.Flush()
            BW.BaseStream.Seek(0, SeekOrigin.Begin)

            Try
                Dim rTex As Texture = Texture.FromStream(xDevice, MS, Usage.None, Pool.Managed)
                rTex.AutoMipGenerationFilter = TextureFilter.Linear

                Return rTex ', BitmapWidth, BitmapHeight, bitmaps.GetValue(index, 8), Microsoft.DirectX.Direct3D.Usage.AutoGenerateMipMap Or Microsoft.DirectX.Direct3D.Usage.Dynamic, Microsoft.DirectX.Direct3D.Format.A8R8G8B8, Microsoft.DirectX.Direct3D.Pool.Default, Microsoft.DirectX.Direct3D.Filter.Linear, Microsoft.DirectX.Direct3D.Filter.Linear, 0)
            Catch ex As Direct3D9Exception
                Try
                    MS.SetLength(0)
                    DDS.MipMapCount = bitmaps.GetValue(index, 8)
                    DDS.writeStruct(BW)
                    BW.Write(Raw)
                    BW.Flush()
                    BW.BaseStream.Seek(0, SeekOrigin.Begin)
                    Return Texture.FromStream(xDevice, MS, Usage.None, Pool.Managed)
                Catch ex2 As Direct3D9Exception
                    Try
                        MS.SetLength(0)
                        DDS.MipMapCount = 0
                        DDS.writeStruct(BW)
                        BW.Write(Raw)
                        BW.Flush()
                        BW.BaseStream.Seek(0, SeekOrigin.Begin)
                        Return Texture.FromStream(xDevice, MS, Usage.None, Pool.Managed)
                    Catch
                    End Try
                End Try
            End Try
            Return Nothing
        Catch
            Return Nothing
        End Try
    End Function
    Public Shared Sub Deswizzle(ByVal bitmTag As Magic.Core.Tag)
        Try
            Dim bitmaps As Array = bitmTag("bitmaps")
            Dim Count As Integer = bitmaps.GetLength(0)
            Dim pixelData() As Byte = bitmTag("processed pixel data")
            For x As Integer = 0 To Count - 1
                Dim index As Integer = x
                Dim bFlags As bitmType = bitmaps.GetValue(index, 6)
                If (bFlags And &H8) > 0 Then

                    Dim Size As Integer = 0
                    Dim Offset As Integer = bitmaps.GetValue(index, 10)

                    If Count > 1 Then
                        If index = Count - 1 Then
                            Size = pixelData.Length - Offset
                        Else
                            Size = bitmaps.GetValue(index + 1, 10) - Offset
                        End If
                    Else
                        Size = pixelData.Length
                    End If

                    Dim Raw(Size - 1) As Byte
                    Array.Copy(pixelData, Offset, Raw, 0, Size)

                    If Raw Is Nothing Then Exit Sub

                    If Raw.Length = 0 Then Exit Sub

                    Dim BitmapWidth As Integer = bitmaps.GetValue(index, 1)
                    Dim BitmapHeight As Integer = bitmaps.GetValue(index, 2)
                    Dim BitmapDepth As Integer = bitmaps.GetValue(index, 3)
                    Dim bFormat As bitmFormat = bitmaps.GetValue(index, 5)

                    Select Case bFormat
                        Case bitmFormat.BITM_FORMAT_DXT1
                            Raw = Raw
                        Case bitmFormat.BITM_FORMAT_DXT2AND3
                            Raw = Raw
                        Case bitmFormat.BITM_FORMAT_DXT4AND5
                            Raw = Raw
                        Case bitmFormat.BITM_FORMAT_A8
                            Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 8, SwizzleType.DeSwizzle)
                        Case bitmFormat.BITM_FORMAT_Y8
                            Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 8, SwizzleType.DeSwizzle)
                        Case bitmFormat.BITM_FORMAT_AY8
                            Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 8, SwizzleType.DeSwizzle)
                        Case bitmFormat.BITM_FORMAT_A8Y8
                            Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 16, SwizzleType.DeSwizzle)
                        Case bitmFormat.BITM_FORMAT_R5G6B5
                            Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 16, SwizzleType.DeSwizzle)
                        Case bitmFormat.BITM_FORMAT_A1R5G5B5
                            Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 16, SwizzleType.DeSwizzle)
                        Case bitmFormat.BITM_FORMAT_A4R4G4B4
                            Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 16, SwizzleType.DeSwizzle)
                        Case bitmFormat.BITM_FORMAT_X8R8G8B8
                            Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 32, SwizzleType.DeSwizzle)
                        Case bitmFormat.BITM_FORMAT_A8R8G8B8
                            Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 32, SwizzleType.DeSwizzle)
                        Case bitmFormat.BITM_FORMAT_P8
                            Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 8, SwizzleType.DeSwizzle)
                        Case bitmFormat.BITM_FORMAT_A8_LIGHTMAP
                            Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 8, SwizzleType.DeSwizzle)
                    End Select
                    Array.Copy(Raw, 0, pixelData, Offset, Size)
                    bitmaps.SetValue(bFlags Xor &H8, index, 6)
                End If

            Next
            bitmTag("bitmaps") = bitmaps
            bitmTag("processed pixel data") = pixelData
            'bitmTag.Write("C:\Tags\hangemhigh.bitmap", MagicInterface.magicMap.Library)
        Catch

        End Try
    End Sub
    'Return Microsoft.DirectX.Direct3D.TextureLoader.FromCubeStream(xDevice, MS)
    Public Function Cube(Optional ByVal index As Integer = 0, Optional ByVal Lightmap As Boolean = False, Optional ByVal mips As Integer = 0) As CubeTexture
        Try
            Dim Size As Integer = 0
            Dim Offset As Integer = bitmaps.GetValue(index, 10)
            If Count > 1 Then
                If index = Count - 1 Then
                    Size = pixelData.Length - Offset
                Else
                    Size = bitmaps.GetValue(index + 1, 10) - Offset
                End If
            Else
                Size = pixelData.Length
            End If

            Dim DDS As New DDS_HEADER_STRUCTURE(bitmaps, index)
            Dim Raw(Size - 1) As Byte
            Array.Copy(pixelData, Offset, Raw, 0, Size)


            Dim BitmapWidth As Integer = bitmaps.GetValue(index, 1)
            Dim BitmapHeight As Integer = bitmaps.GetValue(index, 2)
            Dim BitmapDepth As Integer = bitmaps.GetValue(index, 3)
            Dim bFormat As bitmFormat = bitmaps.GetValue(index, 5)
            Dim bFlags As bitmType = bitmaps.GetValue(index, 6)

            If (bFlags And &H8) = 8 Then
                Select Case bFormat
                    Case bitmFormat.BITM_FORMAT_DXT1
                        Raw = Raw
                    Case bitmFormat.BITM_FORMAT_DXT2AND3
                        Raw = Raw
                    Case bitmFormat.BITM_FORMAT_DXT4AND5
                        Raw = Raw
                    Case bitmFormat.BITM_FORMAT_A8
                        Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 8, SwizzleType.DeSwizzle)
                    Case bitmFormat.BITM_FORMAT_Y8
                        Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 8, SwizzleType.DeSwizzle)
                    Case bitmFormat.BITM_FORMAT_AY8
                        Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 8, SwizzleType.DeSwizzle)
                    Case bitmFormat.BITM_FORMAT_A8Y8
                        Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 16, SwizzleType.DeSwizzle)
                    Case bitmFormat.BITM_FORMAT_R5G6B5
                        Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 16, SwizzleType.DeSwizzle)
                    Case bitmFormat.BITM_FORMAT_A1R5G5B5
                        Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 16, SwizzleType.DeSwizzle)
                    Case bitmFormat.BITM_FORMAT_A4R4G4B4
                        Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 16, SwizzleType.DeSwizzle)
                    Case bitmFormat.BITM_FORMAT_X8R8G8B8
                        Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 32, SwizzleType.DeSwizzle)
                    Case bitmFormat.BITM_FORMAT_A8R8G8B8
                        Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 32, SwizzleType.DeSwizzle)
                    Case bitmFormat.BITM_FORMAT_P8
                        Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 8, SwizzleType.DeSwizzle)
                    Case bitmFormat.BITM_FORMAT_A8_LIGHTMAP
                        Raw = Swizzle.Swizzle(Raw, BitmapWidth, BitmapHeight, -1, 8, SwizzleType.DeSwizzle)
                End Select
            End If

            Dim firstMip As Integer = Magic.Core.Tag.CalculateBitmapSize(BitmapWidth, BitmapHeight, BitmapDepth, 0, bFormat, 0)
            Dim allMips As Integer = Magic.Core.Tag.CalculateBitmapSize(BitmapWidth, BitmapHeight, BitmapDepth, 0, bFormat, 6)

            Dim Chunk(firstMip * 6 - 1) As Byte

            For x As Integer = 0 To 5
                Array.Copy(Raw, allMips * x, Chunk, x * firstMip, firstMip)
            Next


            Dim MS As New MemoryStream
            Dim BW As New BinaryWriter(MS)

            If bFormat = bitmFormat.BITM_FORMAT_P8 Or bFormat = bitmFormat.BITM_FORMAT_A8 Or bFormat = bitmFormat.BITM_FORMAT_AY8 Or bFormat = bitmFormat.BITM_FORMAT_Y8 Then
                DDS.HeaderFlags = &H1007
                DDS.PixelFlags = &H20000
                DDS.RGBBitCount = 8
                DDS.RBitMask = &HFF
                DDS.GBitMask = 0
                DDS.BBitMask = 0
                DDS.RGBAlphaBitMask = 0
                DDS.Caps1 = &H100
            End If
            If bFormat = bitmFormat.BITM_FORMAT_A8 Then
                '  DDS.MipMapCount = 0
            End If
            DDS.MipMapCount = mips
            DDS.writeStruct(BW)
            BW.Write(Chunk)
            BW.Flush()
            BW.BaseStream.Seek(0, SeekOrigin.Begin)

            Try
                'DDS.MipMapCount = bitmaps.GetValue(index, 8)
                'DDS.MipMapCount = 6 'bitmaps.GetValue(index, 8)
                Return CubeTexture.FromStream(xDevice, MS)
            Catch ex As Direct3D9Exception
                Return Nothing
            End Try
        Catch
            Return Nothing
        End Try
    End Function

#Region "DDS Library"
    'BITM
    Enum bitmFormat As Short
        BITM_FORMAT_A8 = 0
        BITM_FORMAT_Y8 = 1
        BITM_FORMAT_AY8 = 2
        BITM_FORMAT_A8Y8 = 3
        BITM_FORMAT_R5G6B5 = 6
        BITM_FORMAT_A1R5G5B5 = 8
        BITM_FORMAT_A4R4G4B4 = 9
        BITM_FORMAT_X8R8G8B8 = 10
        BITM_FORMAT_A8R8G8B8 = 11
        BITM_FORMAT_DXT1 = 14
        BITM_FORMAT_DXT2AND3 = 15
        BITM_FORMAT_DXT4AND5 = 16
        BITM_FORMAT_P8 = 17
        BITM_FORMAT_A8_LIGHTMAP = 18

        BITM_TYPE_2D = 0
        BITM_TYPE_3D = 1
        BITM_TYPE_CUBEMAP = 2

        BITM_FLAG_LINEAR = (1 << 4)
    End Enum
    Enum bitmType As Short
        Texture_2D = 0
        Texture_3D = 1
        Cubemap = 2
        White = 3
    End Enum
    'DDS
    'The dwFlags member of the modified DDSURFACEDESC2 structure can be set to one or more of the following values.
    Enum DDSEnum As Integer
        DDSD_CAPS = &H1
        DDSD_HEIGHT = &H2
        DDSD_WIDTH = &H4
        DDSD_PITCH = &H8
        DDSD_PIXELFORMAT = &H1000
        DDSD_MIPMAPCOUNT = &H20000
        DDSD_LINEARSIZE = &H80000
        DDSD_DEPTH = &H800000

        DDPF_ALPHAPIXELS = &H1
        DDPF_FOURCC = &H4
        DDPF_RGB = &H40

        'The dwCaps1 member of the DDSCAPS2 structure can be set to one or more of the following values.
        DDSCAPS_COMPLEX = &H8
        DDSCAPS_TEXTURE = &H1000
        DDSCAPS_MIPMAP = &H400000

        'The dwCaps2 member of the DDSCAPS2 structure can be set to one or more of the following values.
        DDSCAPS2_CUBEMAP = &H200
        DDSCAPS2_CUBEMAP_POSITIVEX = &H400
        DDSCAPS2_CUBEMAP_NEGATIVEX = &H800
        DDSCAPS2_CUBEMAP_POSITIVEY = &H1000
        DDSCAPS2_CUBEMAP_NEGATIVEY = &H2000
        DDSCAPS2_CUBEMAP_POSITIVEZ = &H4000
        DDSCAPS2_CUBEMAP_NEGATIVEZ = &H8000
        DDSCAPS2_VOLUME = &H200000
    End Enum
    Public Structure DDS_HEADER_STRUCTURE
        Public magic As String '"DDS "
        Public HeaderFlags As Integer
        Public BitmapHeight As Integer
        Public BitmapWidth As Integer
        Public PitchOrLinearSize As Integer
        Public BitmapDepth As Integer 'Only used for volume textures.
        Public MipMapCount As Integer 'Total Number of MipMaps
        Public PixelFlags As Integer  '4
        Public FourCC As String 'DXT1, DXT2, etc..
        Public bpp As Integer
        Public RGBBitCount As Integer
        Public RBitMask As Integer
        Public GBitMask As Integer
        Public BBitMask As Integer
        Public RGBAlphaBitMask As Integer
        Public Caps1 As Integer
        Public Caps2 As Integer
        Public Sub writeStruct(ByRef bw As BinaryWriter)
            bw.BaseStream.WriteByte(Asc(Mid("DDS ", 1, 1)))
            bw.BaseStream.WriteByte(Asc(Mid("DDS ", 2, 1)))
            bw.BaseStream.WriteByte(Asc(Mid("DDS ", 3, 1)))
            bw.BaseStream.WriteByte(Asc(Mid("DDS ", 4, 1)))
            '2
            bw.Write(124)
            '3
            bw.Write(HeaderFlags)
            '4
            bw.Write(BitmapHeight)
            '5
            bw.Write(BitmapWidth)
            '6
            bw.Write(PitchOrLinearSize)
            '7
            bw.Write(BitmapDepth)
            '8
            bw.Write(MipMapCount)
            For x As Integer = 0 To 10
                bw.Write(0)
            Next
            '20
            bw.Write(32)
            '21
            bw.Write(PixelFlags)
            '22
            bw.BaseStream.WriteByte(Asc(Mid(FourCC, 1, 1)))
            bw.BaseStream.WriteByte(Asc(Mid(FourCC, 2, 1)))
            bw.BaseStream.WriteByte(Asc(Mid(FourCC, 3, 1)))
            bw.BaseStream.WriteByte(Asc(Mid(FourCC, 4, 1)))
            '23
            bw.Write(RGBBitCount)
            bw.Write(RBitMask)
            bw.Write(GBitMask)
            bw.Write(BBitMask)
            bw.Write(RGBAlphaBitMask)
            bw.Write(Caps1)
            bw.Write(Caps2)
            bw.Write(0)
            bw.Write(0)
            bw.Write(0)
        End Sub
        '//////////////////////////////////////////////////////
        '// Generate a DDS Header
        '//////////////////////////////////////////////////////

        Public Sub New(ByVal bitmap As Array, ByVal Index As Integer)
            magic = "DDS "

            'Width of the main image in pixels
            BitmapWidth = bitmap.GetValue(Index, 1)

            'Height of the main image in pixels
            BitmapHeight = bitmap.GetValue(Index, 2)

            'For volume textures, this is the depth of the volume.
            'dwFlags should include DDSD_DEPTH in this case.
            BitmapDepth = bitmap.GetValue(Index, 3)

            'Flags to indicate valid fields. Always include DDSD_CAPS, DDSD_PIXELFORMAT,
            'DDSD_WIDTH, DDSD_HEIGHT and either DDSD_PITCH or DDSD_LINEARSIZE.
            HeaderFlags = HeaderFlags Or DDSEnum.DDSD_CAPS
            HeaderFlags = HeaderFlags Or DDSEnum.DDSD_PIXELFORMAT
            HeaderFlags = HeaderFlags Or DDSEnum.DDSD_WIDTH
            HeaderFlags = HeaderFlags Or DDSEnum.DDSD_HEIGHT

            Dim bType As bitmType = bitmap.GetValue(Index, 4)
            Dim bFormat As bitmFormat = bitmap.GetValue(Index, 5)
            If bFormat = bitmFormat.BITM_FORMAT_P8 Then
                bFormat = bitmFormat.BITM_FORMAT_A8R8G8B8
            End If
            Select Case bFormat
                Case bitmFormat.BITM_FORMAT_DXT1, bitmFormat.BITM_FORMAT_DXT2AND3, bitmFormat.BITM_FORMAT_DXT4AND5
                    HeaderFlags = HeaderFlags Or DDSEnum.DDSD_LINEARSIZE
                Case Else
                    HeaderFlags = HeaderFlags Or DDSEnum.DDSD_PITCH
            End Select


            If BitmapWidth > BitmapHeight Then
                Select Case BitmapHeight
                    Case 1
                        MipMapCount = 0
                    Case 2
                        MipMapCount = 1
                    Case 4
                        MipMapCount = 2
                    Case 8
                        MipMapCount = 3
                    Case 16
                        MipMapCount = 4
                    Case 32
                        MipMapCount = 5
                    Case 64
                        MipMapCount = 6
                    Case 128
                        MipMapCount = 7
                    Case 256
                        MipMapCount = 8
                    Case 512
                        MipMapCount = 9
                    Case 1024
                        MipMapCount = 10
                    Case 2048
                        MipMapCount = 11
                    Case 4096
                        MipMapCount = 12
                    Case Else
                        MipMapCount = 0
                End Select
            Else
                Select Case BitmapWidth
                    Case 1
                        MipMapCount = 0
                    Case 2
                        MipMapCount = 1
                    Case 4
                        MipMapCount = 2
                    Case 8
                        MipMapCount = 3
                    Case 16
                        MipMapCount = 4
                    Case 32
                        MipMapCount = 5
                    Case 64
                        MipMapCount = 6
                    Case 128
                        MipMapCount = 7
                    Case 256
                        MipMapCount = 8
                    Case 512
                        MipMapCount = 9
                    Case 1024
                        MipMapCount = 10
                    Case 2048
                        MipMapCount = 11
                    Case 4096
                        MipMapCount = 12
                    Case Else
                        MipMapCount = 0
                End Select
            End If
            MipMapCount -= 1
            If MipMapCount <> 0 Then MipMapCount = 0
            'MipMapCount = bitmap.GetValue(Index, 8)
            If MipMapCount > 0 Then HeaderFlags = HeaderFlags Or DDSEnum.DDSD_MIPMAPCOUNT

            'For uncompressed formats, this is the number of bytes per scan line (DWORD aligned) for the main
            'image. dwFlags should include DDSD_PITCH in this case. For compressed formats, this is the (total)
            'number of bytes for the main image. dwFlags should be include DDSD_LINEARSIZE in this case.
            RGBBitCount = 0
            Select Case bFormat
                Case bitmFormat.BITM_FORMAT_A8
                    RGBBitCount = 8
                Case bitmFormat.BITM_FORMAT_A8_LIGHTMAP
                    RGBBitCount = 8
                Case bitmFormat.BITM_FORMAT_Y8
                    RGBBitCount = 8
                Case bitmFormat.BITM_FORMAT_P8
                    RGBBitCount = 8
                Case bitmFormat.BITM_FORMAT_AY8
                    RGBBitCount = 8
                Case bitmFormat.BITM_FORMAT_A8Y8
                    RGBBitCount = 16
                Case bitmFormat.BITM_FORMAT_R5G6B5
                    RGBBitCount = 16
                Case bitmFormat.BITM_FORMAT_A1R5G5B5
                    RGBBitCount = 16
                Case bitmFormat.BITM_FORMAT_A4R4G4B4
                    RGBBitCount = 16
                Case bitmFormat.BITM_FORMAT_X8R8G8B8
                    RGBBitCount = 32
                Case bitmFormat.BITM_FORMAT_A8R8G8B8
                    RGBBitCount = 32
            End Select


            If (HeaderFlags And DDSEnum.DDSD_LINEARSIZE) = DDSEnum.DDSD_LINEARSIZE Then PitchOrLinearSize = bitmap.GetValue(Index, 10)
            If (HeaderFlags And DDSEnum.DDSD_PITCH) = DDSEnum.DDSD_PITCH Then PitchOrLinearSize = BitmapWidth * (RGBBitCount / 8)


            'Flags to indicate valid fields. Uncompressed formats will usually use DDPF_RGB to indicate
            'an RGB format, while compressed formats will use DDPF_FOURCC with a four-character code. 
            'This is accomplished in the below structure.

            'This is the four-character code for compressed formats. dwFlags should include DDPF_FOURCC in
            'this case. For DXTn compression, this is set to "DXT1", "DXT2", "DXT3", "DXT4", or "DXT5". 
            PixelFlags = 0
            Select Case bFormat
                Case &HE
                    FourCC = "DXT1"
                    PixelFlags = PixelFlags Or DDSEnum.DDPF_FOURCC
                Case &HF
                    FourCC = "DXT3"
                    PixelFlags = PixelFlags Or DDSEnum.DDPF_FOURCC
                Case &H10
                    FourCC = "DXT4"
                    PixelFlags = PixelFlags Or DDSEnum.DDPF_FOURCC
                Case Else
                    FourCC = Chr(0) & Chr(0) & Chr(0) & Chr(0)
                    PixelFlags = PixelFlags Or DDSEnum.DDPF_RGB
            End Select

            'For RGB formats, this is the total number of bits in the format. dwFlags should include DDPF_RGB
            'in this case. This value is usually 16, 24, or 32. For A8R8G8B8, this value would be 32. 
            Select Case bFormat
                Case bitmFormat.BITM_FORMAT_A8
                    RGBBitCount = 0
                    bpp = 8
                    PixelFlags = PixelFlags Or DDSEnum.DDPF_ALPHAPIXELS
                Case bitmFormat.BITM_FORMAT_Y8
                    RGBBitCount = 0
                    bpp = 8
                    PixelFlags = PixelFlags Or DDSEnum.DDPF_ALPHAPIXELS
                Case bitmFormat.BITM_FORMAT_P8
                    RGBBitCount = 0
                    bpp = 8
                    PixelFlags = PixelFlags Or DDSEnum.DDPF_ALPHAPIXELS
                Case bitmFormat.BITM_FORMAT_AY8
                    RGBBitCount = 0
                    bpp = 8
                    PixelFlags = PixelFlags Or DDSEnum.DDPF_ALPHAPIXELS
                Case bitmFormat.BITM_FORMAT_A8_LIGHTMAP
                    RGBBitCount = 0
                    bpp = 8
                    PixelFlags = PixelFlags + DDSEnum.DDPF_ALPHAPIXELS
                Case bitmFormat.BITM_FORMAT_A8Y8
                    RGBBitCount = 16
                    bpp = 16
                    PixelFlags = PixelFlags Or DDSEnum.DDPF_ALPHAPIXELS
                Case bitmFormat.BITM_FORMAT_R5G6B5
                    RGBBitCount = 16
                    bpp = 16
                Case bitmFormat.BITM_FORMAT_A1R5G5B5
                    RGBBitCount = 16
                    bpp = 16
                    PixelFlags = PixelFlags Or DDSEnum.DDPF_ALPHAPIXELS
                Case bitmFormat.BITM_FORMAT_A4R4G4B4
                    RGBBitCount = 16
                    bpp = 16
                    PixelFlags = PixelFlags Or DDSEnum.DDPF_ALPHAPIXELS
                Case bitmFormat.BITM_FORMAT_X8R8G8B8
                    RGBBitCount = 32
                    bpp = 32
                    PixelFlags = PixelFlags Or DDSEnum.DDPF_ALPHAPIXELS
                Case bitmFormat.BITM_FORMAT_A8R8G8B8
                    RGBBitCount = 32
                    bpp = 32
                    PixelFlags = PixelFlags Or DDSEnum.DDPF_ALPHAPIXELS
                Case bitmFormat.BITM_FORMAT_DXT1
                    bpp = 4
                    RGBBitCount = 0
                Case bitmFormat.BITM_FORMAT_DXT2AND3, bitmFormat.BITM_FORMAT_DXT4AND5
                    bpp = 8
                    RGBBitCount = 0
                    PixelFlags = PixelFlags Or DDSEnum.DDPF_ALPHAPIXELS
                Case Else
                    RGBBitCount = 0
                    bpp = 0
            End Select

            'For RGB formats, this contains the masks for the red, green, and blue channels. For A8R8G8B8, these
            'values would be 0x00ff0000, 0x0000ff00, and 0x000000ff respectively. 

            Select Case bFormat
                Case bitmFormat.BITM_FORMAT_R5G6B5
                    RBitMask = &HF800
                    GBitMask = &H7E0
                    BBitMask = &H1F
                    RGBAlphaBitMask = &H0
                Case bitmFormat.BITM_FORMAT_A1R5G5B5
                    RBitMask = &H7C00
                    GBitMask = &H3E0
                    BBitMask = &H1F
                    RGBAlphaBitMask = &H8000
                Case bitmFormat.BITM_FORMAT_A4R4G4B4
                    RBitMask = &HF000
                    GBitMask = &HF0
                    BBitMask = &HF
                    RGBAlphaBitMask = &HF00000
                Case bitmFormat.BITM_FORMAT_X8R8G8B8
                    RBitMask = &HFF0000
                    GBitMask = &HFF00
                    BBitMask = &HFF
                    RGBAlphaBitMask = &HFF000000
                Case bitmFormat.BITM_FORMAT_A8R8G8B8
                    RBitMask = &HFF0000
                    GBitMask = &HFF00
                    BBitMask = &HFF
                    RGBAlphaBitMask = &HFF000000
                Case bitmFormat.BITM_FORMAT_A8, bitmFormat.BITM_FORMAT_Y8, bitmFormat.BITM_FORMAT_A8_LIGHTMAP, bitmFormat.BITM_FORMAT_P8, bitmFormat.BITM_FORMAT_AY8
                    RBitMask = &HFF
                    GBitMask = &HFF
                    BBitMask = &HFF
                    RGBAlphaBitMask = &HFF
                Case Else
                    RBitMask = 0
                    GBitMask = 0
                    BBitMask = 0
                    RGBAlphaBitMask = &H0
            End Select

            'For RGB formats, this contains the mask for the alpha channel, if any. dwFlags should include 
            'DDPF_ALPHAPIXELS in this case. For A8R8G8B8, this value would be 0xff000000. 
            '^^ This was set in the previous block of code.


            'DDS files should always include DDSCAPS_TEXTURE. If the file contains mipmaps, DDSCAPS_MIPMAP
            'should be set. For any DDS file with more than one main surface,such as a mipmaps, cubic
            'environment map, or volume texture, DDSCAPS_COMPLEX should also be set. 
            Caps1 = Caps1 Or DDSEnum.DDSCAPS_TEXTURE
            'If b2.num_mipmaps > 0 Then caps1 = caps1 + DDSEnum.DDSCAPS_MIPMAP
            If MipMapCount > 0 Then
                Caps1 = Caps1 Or DDSEnum.DDSCAPS_MIPMAP
            End If
            If MipMapCount > 0 Or bType = bitmType.Cubemap Then
                Caps1 = Caps1 Or DDSEnum.DDSCAPS_COMPLEX
            End If
            'For cubic environment maps, DDSCAPS2_CUBEMAP should be included as well as one or more faces of
            'the map (DDSCAPS2_CUBEMAP_POSITIVEX, DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY,
            ' DDSCAPS2_CUBEMAP_NEGATIVEY, DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ). For volume
            'textures, DDSCAPS2_VOLUME should be included. 
            '******************************************************************************
            'This is where I stopped - this code needs to be added for cubemaps.
            '******************************************************************************
            Caps2 = 0
            If bType = bitmType.Cubemap Then
                Caps2 = DDSEnum.DDSCAPS2_CUBEMAP Or DDSEnum.DDSCAPS2_CUBEMAP_NEGATIVEX Or DDSEnum.DDSCAPS2_CUBEMAP_POSITIVEZ Or DDSEnum.DDSCAPS2_CUBEMAP_POSITIVEY Or DDSEnum.DDSCAPS2_CUBEMAP_POSITIVEX Or DDSEnum.DDSCAPS2_CUBEMAP_NEGATIVEZ Or DDSEnum.DDSCAPS2_CUBEMAP_NEGATIVEY
            End If
        End Sub
    End Structure
#End Region
End Class
